package com.xnew.utils;

import com.alibaba.fastjson.JSONObject;
import com.xnew.exception.CustomException;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * <p>
 * Title: FileUtil.java
 * </p>
 * <p>
 * Copyright: Copyright (c) 2019
 * </p>
 * <p>
 * Company: www.xnewtech.com
 * </p>
 *
 * @author tangw
 * @version 1.0
 * @date 2019年7月24日 下午7:24:33
 */
@Configuration
public class FileUtil {

    public static final String EXPIREDIN = "200";// 登陆有效期（秒）S
    public static final String LOG_CONTENT_TYPE = "application/x-www-form-urlencoded";
    public static final String UPLOAD_CONTENT_TYPE = "multipart/form-data";
    public static final MediaType MEDIA_TYPE_BINARY = MediaType.parse("application/octet-stream");
    /**
     * 非结构化平台
     */
    public static String USER_NAME = "AMIS";// 登陆用户账号
    public static String PASSWORD = "U7*AMIS";// 登陆用户密码
    public static String LOG_URL = "http://usdpapp.cinda.ccb/login";
    public static String UPLOAD_URL = "http://usdpapp.cinda.ccb/files";
    public static String GET_FILE_DESC_URL = "http://usdpapp.cinda.ccb/files";
    public static final String ACCEPT = "application/octet-stream";

    OkHttpClient client = new OkHttpClient();

    public static void downloadModel(String filename, HttpServletResponse response) throws IOException {
        // 发送给客户端的数据
        OutputStream outputStream = response.getOutputStream();
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        // 读取filename
        bis = new BufferedInputStream(new FileInputStream(new File("src/main/resources/templates/" + filename)));
        int i = bis.read(buff);
        while (i != -1) {
            outputStream.write(buff, 0, buff.length);
            outputStream.flush();
            i = bis.read(buff);
        }
        bis.close();
        outputStream.close();
    }


    /**
     * 获取登录token
     *
     * @param curr_id 当前登录人id
     * @return token
     * @throws IOException
     */
    public String login(String curr_id) throws IOException {
        RequestBody formBody = new FormBody.Builder().add("username", FileUtil.USER_NAME)
                .add("password", FileUtil.PASSWORD).add("individualUserID", curr_id).add("expiredIn", EXPIREDIN)
                .build();
        Request request = new Request.Builder().url(FileUtil.LOG_URL).addHeader("content-type", LOG_CONTENT_TYPE)
                .post(formBody).build();
        try (Response response = client.newCall(request).execute()) {
            String res = response.body().string();
            JSONObject json = JSONObject.parseObject(res);
            return json.getString("token");
        }
    }

    /**
     * 上传文件
     *
     * @param file
     * @param curr_id 当前用户id
     * @return 格式：{"message":"...","fileID":"....","versionID":"..."}
     * @throws Exception
     */
    public String uploadFile(File file, String curr_id) throws Exception {
        RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_BINARY, file))
                .build();

        Request request = new Request.Builder().url(FileUtil.UPLOAD_URL).addHeader("content-type", UPLOAD_CONTENT_TYPE)
                .addHeader("token", login(curr_id)).post(requestBody).build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response.body().string());
            }
            return response.body().string();
        }
    }

    /**
     * @param curr_id  用户id
     * @param fileName 文件名
     * @return 返回非结构化平台文件信息对象
     * @throws Exception
     * @方法名：uploadFile
     * @功能说明：上传文件到非结构化平台
     * @author tangwei1
     * @date 2019年7月24日 下午7:23:30
     * spring文件对象
     */
    public String uploadFileOutputStream(ByteArrayOutputStream bos, String curr_id, String fileName) throws Exception {
        try {
            RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                    .addFormDataPart("file", fileName, RequestBody.create(MEDIA_TYPE_BINARY, bos.toByteArray()))
                    .build();
            Request request = new Request.Builder().url(FileUtil.UPLOAD_URL).addHeader("token", login(curr_id))
                    .post(requestBody).build();
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response.body().string());
                }
                return response.body().string();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                bos.close();
            }
        }
        return null;
    }

    /**
     * @param content  spring文件对象
     * @param curr_id  用户id
     * @param fileName 文件名
     * @return 返回非结构化平台文件信息对象
     * @throws Exception
     * @方法名：uploadFile
     * @功能说明：上传文件到非结构化平台
     * @author tangwei1
     * @date 2019年7月24日 下午7:23:30
     */
    public String uploadFile(MultipartFile content, String curr_id, String fileName) throws Exception {

        InputStream is = null;
        ByteArrayOutputStream bos = null;
        try {
            int len = 0;
            byte[] buffer = new byte[1048];
            bos = new ByteArrayOutputStream();

            is = content.getInputStream();
            while ((len = is.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
            is.close();
            RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                    .addFormDataPart("file", fileName, RequestBody.create(MEDIA_TYPE_BINARY, bos.toByteArray()))
                    .build();
            Request request = new Request.Builder().url(FileUtil.UPLOAD_URL).addHeader("token", login(curr_id))
                    .post(requestBody).build();
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("Unexpected code " + response.body().string());
                }
                return response.body().string();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (is != null) {
                is.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param file_id 待下载文件的id
     * @throws IOException
     */
    public InputStream download(String file_id, String curr_id) throws IOException {

        final InputStream[] rIn = new InputStream[1];
        Request request = new Request.Builder().url(FileUtil.UPLOAD_URL + File.separator + file_id)// 下载文件的路径
                .addHeader("Accept", FileUtil.ACCEPT).addHeader("token", login(curr_id)).build();

        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) {
            throw new IOException("Unexpected code " + response);
        }
        InputStream in = response.body().byteStream();
        rIn[0] = in;
        return rIn[0];
    }

    /**
     * 下载文件后上传
     *
     * @param file_id 待下载文件的id
     * @throws IOException
     */
    public String downloadAndUpload(String file_id, String curr_id, String fileName) throws IOException {
        Request request = new Request.Builder().url(FileUtil.UPLOAD_URL + File.separator + file_id)// 下载文件的路径
                .addHeader("Accept", FileUtil.ACCEPT).addHeader("token", login(curr_id)).build();

        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) {
            throw new IOException("Unexpected code " + response);
        }
        InputStream is = response.body().byteStream();
        ByteArrayOutputStream bos = null;
        try {
            int len = 0;
            byte[] buffer = new byte[1048];
            bos = new ByteArrayOutputStream();
            while ((len = is.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
            is.close();
            RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                    .addFormDataPart("file", fileName, RequestBody.create(MEDIA_TYPE_BINARY, bos.toByteArray()))
                    .build();
            Request sendRequest = new Request.Builder().url(FileUtil.UPLOAD_URL).addHeader("token", login(curr_id))
                    .post(requestBody).build();
            try (Response sendResponse = client.newCall(sendRequest).execute()) {
                if (!sendResponse.isSuccessful()) {
                    throw new IOException("Unexpected code " + sendResponse.body().string());
                }
                return sendResponse.body().string();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                is.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
        return null;
    }

    /**
     * 下载文件后上传
     *
     * @throws IOException
     */
    public String uploadBytes(byte[] bs, String fileName, String curr_id) throws IOException {

        try {
            RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                    .addFormDataPart("file", fileName, RequestBody.create(MEDIA_TYPE_BINARY, bs))
                    .build();
            Request sendRequest = new Request.Builder().url(FileUtil.UPLOAD_URL).addHeader("token", login(curr_id))
                    .post(requestBody).build();
            try (Response sendResponse = client.newCall(sendRequest).execute()) {
                if (!sendResponse.isSuccessful()) {
                    throw new IOException("Unexpected code " + sendResponse.body().string());
                }
                return sendResponse.body().string();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
        return null;
    }

    /**
     * 删除非结构话数据平台的文件
     *
     * @param file_id
     * @param curr_id
     * @return
     * @throws Exception
     */
    public String deleteFile(String file_id, String curr_id) throws Exception {

        RequestBody requestBody = new FormBody.Builder().add("id", file_id).build();

        Request request = new Request.Builder().url(FileUtil.UPLOAD_URL + File.separator + file_id)
                .addHeader("token", login(curr_id)).delete(requestBody).build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    /**
     * 获取文件元信息
     *
     * @param
     * @throws Exception
     * @return{"fileID":"59e5bf28af736960c4850af4","versionID":"59e5bf28af736960c4850af5","filename":"QQ20170912151943.png","folder":"/客户信息系统", "tags":[],"uploadDate":"Tue Oct 17 2017 16:28:24 GMT+0800
     * (CST)","md5":"9192217cdb2d5a008b630084bfbf4f52","customProperties":"{}"}
     */
    public String getFileDesc(String file_id, String curr_id) throws Exception {
        Request request = new Request.Builder().url(FileUtil.GET_FILE_DESC_URL + File.separator + file_id)
                .addHeader("token", login(curr_id)).get().build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response + response.body().string());
            }
            return response.body().string();
        }
    }

    @Value("${FileUtil.USER_NAME}")
    public void setUSER_NAME(String USER_NAME) {
        FileUtil.USER_NAME = USER_NAME;
    }

    @Value("${FileUtil.PASSWORD}")
    public void setPASSWORD(String PASSWORD) {
        FileUtil.PASSWORD = PASSWORD;
    }

    @Value("${FileUtil.LOGIN_URL}")
    public void setLOG_URL(String LOG_URL) {
        FileUtil.LOG_URL = LOG_URL;
    }

    @Value("${FileUtil.UPLOAD_URL}")
    public void setUPLOAD_URL(String UPLOAD_URL) {
        FileUtil.UPLOAD_URL = UPLOAD_URL;
    }

    @Value("${FileUtil.GET_FILE_DESC_URL}")
    public void setGET_FILE_DESC_URL(String GET_FILE_DESC_URL) {
        FileUtil.GET_FILE_DESC_URL = GET_FILE_DESC_URL;
    }



    //通用上传文件到服务器返回文件路径
    public String Myupload(MultipartFile file, String filePath) {
        //上传到服务器的地址
        File upload = null;
        //上传到服务器的文件名
        String fileName = file.getOriginalFilename();

        if (fileName.contains("/")) {
            fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
        }

        upload = new File(filePath);
        if (!upload.exists()) {
            upload.mkdirs();
        }
        try {
            org.apache.commons.io.FileUtils.copyInputStreamToFile(file.getInputStream(), new File(upload + File.separator + fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return  filePath+File.separator+fileName;
    }


    /**
     * 文件写入本地
     * @param inputStream
     * @param out
     */
    public static void FileWriteToLocal(InputStream inputStream,File out)
    {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(out);
            byte[] buffer = new byte[1024*256];//一次读取 256K
            //写入本地
            while (true)
            {
                int read = inputStream.read(buffer);
                outputStream.write(buffer,0,read);
                if(read<buffer.length)
                {
                    break;
                }
            }
            outputStream.flush();
            outputStream.close();
        }catch (Exception e)
        {
            throw  new CustomException(500,"文件保存失败");
        }
        finally {
            if(outputStream!=null)
            {
               try {
                   outputStream.close();
                   outputStream = null;
               }catch (Exception e2)
               {

               }
            }
        }
    }


}
